package com.fingard.dsp.bank.directbank.citicunion01;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.codec.binary.Base64;

import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.fc11.util.RSACoder;
import com.fingard.dsp.bank.directbank.vbao02.util.RSAUtil;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

public class CITICUnion01Base extends DirectBase  {
	protected String getCharset() {
		return getBankConfig().getCharset("UTF-8");
	}



	protected String[] sendToBank(String p_reqStr, String p_for) throws Exception{
		String[] retStr = new String[]{"",""};
		String url = bankFront.getUrl(p_for);
		WriteBankUrlLogLn(url);
		WriteBankLogStep2(p_reqStr);
		WebRequest tmpWebRequest = new WebRequest(url);
		tmpWebRequest.setConnectTimeout(60000);
		tmpWebRequest.setRequestProperty("connection", "Close");
		byte[] tmpUpBytes = p_reqStr.getBytes(getCharset());
		retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
		WriteBankLogStep3(retStr[1]);
		if(retStr[0].length() == 0){
			int tmpIndex = retStr[1].indexOf("<");
			if(tmpIndex > 0){
				retStr[1] = retStr[1].substring(tmpIndex);
			}
		}else{
			this.WriteBankLogLn(tmpWebRequest.sbLog);
		}
		return retStr;
	}





	/**
	 * 过滤参数
	 * @author
	 * @param sArray
	 * @return
	 */
	public  Map<String, Object> paraFilter(Map<String, String> sArray) {
		Map<String, Object> result = new HashMap<String, Object>(sArray.size());
		if (sArray == null || sArray.size() <= 0) {
			return result;
		}
		for (String key : sArray.keySet()) {
			String value = sArray.get(key);
			if (value == null || "".equals(value) || "sign".equalsIgnoreCase(key)) {
				continue;
			}
			result.put(key, value);
		}
		return result;
	}


	/**
	 * @author
	 * Map参数格式化为 XML格式
	 *
	 * @param parameters
	 * @return
	 */

	public  String parseXML(SortedMap<String, String> parameters) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set<Entry<String, String>> es = parameters.entrySet();
		Iterator<Entry<String, String>> it = es.iterator();
		while (it.hasNext()) {
			Entry<String, String> entry = (Entry<String, String>)it.next();
			String k = (String)entry.getKey();
			String v = (String)entry.getValue();
			if (null != v && !"".equals(v) && !"appkey".equals(k)) {
				sb.append("<" + k + ">" + parameters.get(k) + "</" + k + ">\n");
			}
		}
		sb.append("</xml>");
		return sb.toString();
	}


	/**
	 * @author
	 * 生产32位随机码
	 *
	 * @return
	 */
	protected String get_nonce_str() throws Exception{
		String time_stamp = DateHelper.getSecsFrom1970();
		//随机字符串 String(32)
		Random random=new Random();
		long randLong = random.nextLong();
		randLong = random.nextLong();
		String nonce_str = time_stamp+String.format("%20d", randLong);
		nonce_str = DigestHelper.cryptoMD5RetHexStr(nonce_str.getBytes());
		return nonce_str;
	}


	/**
	 * @return 返回签名
	 * @author
	 */
	protected String msgSign(Map<String, String> returnMap , String keyPath) throws Exception {
		Map<String, Object> params = paraFilter(returnMap);
        String preStr = StringHelper.mapToString(params, true);
		PrivateKey privateKey = RSAUtil.getRSAPrivateKeyByFileSuffix(keyPath, null, null, "RSA");
		return RSACoder.sign(preStr.getBytes(getCharset()), privateKey, "SHA256WithRSA");
	}



	public static boolean verifySignBySha256( byte[] msgBuf, byte[] sign, String pubKeyPath) {
		Signature signature = null;
		try {
			signature = Signature.getInstance("SHA256WithRSA");

			PublicKey publicKey = RSAUtil.getRSAPublicKeyByFileSuffix(pubKeyPath, null, "RSA");
			signature.initVerify(publicKey);
		} catch(Exception e) {

			throw new RuntimeException("INVALID_PUBKEY");
		}

		try {
			signature.update(msgBuf);
			return signature.verify(sign);
		} catch (SignatureException e) {
			throw new RuntimeException("签名格式不合法");
		}
	}

	public boolean verifySign(String p_xml, String keyPath, StringBuilder p_sb) throws Exception{
		XmlTextReader tmpBkReader = loadBankRespXmlReader(p_xml, p_sb);
		if(tmpBkReader != null){
			if(tmpBkReader.read("/xml")){
				ArrayList<XElement> tmpList = tmpBkReader.readedXElement.getAllChildList();
				if(tmpList != null && tmpList.size() > 0){
					String chkSign = "";
					SortedMap<String,String> returnMap = new TreeMap<String,String>();
					for(int i=0;i<tmpList.size();i++){
						XElement xe = tmpList.get(i);
						if("sign".equals(xe.name)){
							chkSign = xe.innerText;
						}
						else if(StringHelper.hasAnyChar(xe.innerText)){
							returnMap.put(xe.name, xe.innerText);
						}
					}

					Map<String, Object> params = paraFilter(returnMap);
					String preStr =	StringHelper.mapToString( params,true);
					boolean verySignRes=	verifySignBySha256(preStr.getBytes(getCharset()), Base64.decodeBase64(chkSign.getBytes("UTF-8")), keyPath);
					return verySignRes;
				}
				else{
					p_sb.append("用于验签的xml节点为空");
					return false;
				}
			}
			else{
				p_sb.append("用于验签的xml节点为空");
				return false;
			}
		}
		else{
			return false;
		}
	}





}
